import { UserDao } from "../src/dao/UserDao";
import { LogServerHelper } from "../log_server/LogServerHelper";
import { ChargeDao } from "../pay_server/dao/ChargeDao";
import { ErrorCode } from "../src/config/ErrorCode";
import { GameConfig } from "../src/config/GameConfig";
import { GoodConfig } from "../src/config/GoodConfig";
import { ServerConfig } from "../src/config/ServerConfig";
import DateUtil from "../src/engine/utils/DateUtil";
import { Base64Helper } from "../src/engine/utils/Base64Helper";
import { Logger } from "../src/engine/utils/Logger";
import { Md5Helper } from "../src/engine/utils/Md5Helper";
import { WebUtil } from "../src/engine/utils/WebUtil";
import { ResponseModel } from "../src/model/ResponseModel";
import { ServerManager } from "../src/server/ServerManager";
import { SystemSettingDao } from "./dao/SystemSettingDao";
import { GmUserModel } from "./model/GmUserModel";
import { AccountDao } from "../account_server/dao/AccountDao";
import { HttpUtil } from "../src/engine/utils/HttpUtil";
import { GameHttpHelper } from "../src/game/helper/GameHttpHelper";
import { ProtoUtils } from "../src/engine/socketserver/protocol/ProtoUtils";
import { ProtoConfig } from "../src/engine/socketserver/protocol/ProtoConfig";
import { Yuxiaxie_control_history } from "./dao/Yuxiaxie_control_history";
import { LogScoreDao } from "./dao/LogScoreDao";
import { RobotHistoryDao } from "./dao/RobotHistoryDao";
import { Config } from "../src/config/Config";
import { ResourceHistoryDao } from "./dao/ResourceHistoryDao";
import { ShellHelper } from "../src/engine/utils/ShellHelper";
import { LogRateDao } from "./dao/LogRateDao";
import { DailiDao } from "./dao/DailiDao";
const request = require('request');
const crypto = require("crypto");

const routerMap = {
    login: "/login",
    onlinenum: "/onlinenum",
    get_user_list: "/get_user_list",
    get_user_info: "/get_user_info",
    charge_by_gm: "/charge_by_gm",
    update_system_setting: "/update_system_setting",
    get_system_setting: "/get_system_setting",
    yuxiaxie_control: "/yuxiaxie_control",
    get_yuxiaxie_control: "/get_yuxiaxie_control",
    group_list: "/group_list",
    groupDiss: "/groupDiss",
    group_member: "/group_member",
    groupZhanji: "/groupZhanji",
    groupTableList: "/groupTableList",
    robot_list: "/robot_list",
    robot_create: "/robot_create",
    robot_apply: "/robot_apply",
    robot_leave: "/robot_leave",
    get_money_info: "/get_money_info",
    getWaigua_list: "/getWaigua_list",
    set_waigua_list: "/set_waigua_list",
    get_log_score: "/get_log_score",
    get_robot_history: "/get_robot_history",
    get_resource_history: "/get_resource_history",
    set_yuxiaxie_rate: "/set_yuxiaxie_rate",
    get_yuxiaxie_rate: "/get_yuxiaxie_rate",
    get_daili: "/get_daili",
    charge_to_daili: "/charge_to_daili"
}

export class GmReqHandler {

    public static instance: GmReqHandler = new GmReqHandler();


    public init(app) {
        for (const key in routerMap) {
            app.use(routerMap[key], this.onBaseRoot.bind(this))
        }

    }

    private onBaseRoot(req, resp) {
        try {
            let ip: string = WebUtil.getIpByExpressReq(req);
            Logger.log("onBaseRoot=req=", ip, req.baseUrl)
            if (req.baseUrl == routerMap.login) {
                this.checkBody(ip, req, resp, this.on_login.bind(this));
            }
            else if (req.baseUrl == routerMap.get_user_list) {
                this.checkBody_md5(ip, req, resp, this.on_get_user_list.bind(this));
            }
            else if (req.baseUrl == routerMap.onlinenum) {
                this.checkBody_md5(ip, req, resp, this.on_onlinenum.bind(this));
            }
            else if (req.baseUrl == routerMap.charge_by_gm) {
                this.checkBody_md5(ip, req, resp, this.on_charge_by_gm.bind(this));
            }
            else if (req.baseUrl == routerMap.get_user_info) {
                this.checkBody_md5(ip, req, resp, this.on_get_user_info.bind(this));
            }
            else if (req.baseUrl == routerMap.update_system_setting) {
                this.checkBody_md5(ip, req, resp, this.on_update_system_setting.bind(this))
            }
            else if (req.baseUrl == routerMap.get_system_setting) {
                this.checkBody_md5(ip, req, resp, this.on_get_system_setting.bind(this))
            }
            else if (req.baseUrl == routerMap.yuxiaxie_control) {
                this.checkBody_md5(ip, req, resp, this.on_yuxiaxie_control.bind(this))
            }
            else if (req.baseUrl == routerMap.get_yuxiaxie_control) {
                this.checkBody_md5(ip, req, resp, this.on_get_yuxiaxie_control.bind(this))
            }
            else if (req.baseUrl == routerMap.group_list) {
                this.checkBody_md5(ip, req, resp, this.group_list.bind(this))
            }
            else if (req.baseUrl == routerMap.groupDiss) {
                this.checkBody_md5(ip, req, resp, this.groupDiss.bind(this))
            }
            else if (req.baseUrl == routerMap.group_member) {
                this.checkBody_md5(ip, req, resp, this.group_member.bind(this))
            }
            else if (req.baseUrl == routerMap.groupZhanji) {
                this.checkBody_md5(ip, req, resp, this.groupZhanji.bind(this))
            }
            else if (req.baseUrl == routerMap.groupTableList) {
                this.checkBody_md5(ip, req, resp, this.groupTableList.bind(this))
            }
            else if (req.baseUrl == routerMap.robot_list) {
                this.checkBody_md5(ip, req, resp, this.robot_list.bind(this))
            }
            else if (req.baseUrl == routerMap.robot_create) {
                this.checkBody_md5(ip, req, resp, this.robot_create.bind(this))
            }
            else if (req.baseUrl == routerMap.robot_apply) {
                this.checkBody_md5(ip, req, resp, this.robot_apply.bind(this))
            }
            else if (req.baseUrl == routerMap.robot_leave) {
                this.checkBody_md5(ip, req, resp, this.robot_leave.bind(this))
            }
            else if (req.baseUrl == routerMap.get_money_info) {
                this.checkBody_md5(ip, req, resp, this.get_money_info.bind(this))
            }
            else if (req.baseUrl == routerMap.getWaigua_list) {
                this.checkBody_md5(ip, req, resp, this.getWaigua_list.bind(this))
            }
            else if (req.baseUrl == routerMap.set_waigua_list) {
                this.checkBody_md5(ip, req, resp, this.set_waigua_list.bind(this))
            }
            else if (req.baseUrl == routerMap.get_log_score) {
                this.checkBody_md5(ip, req, resp, this.get_log_score.bind(this))
            }
            else if (req.baseUrl == routerMap.get_robot_history) {
                this.checkBody_md5(ip, req, resp, this.on_get_robot_history.bind(this))
            }
            else if (req.baseUrl == routerMap.get_resource_history) {
                this.checkBody_md5(ip, req, resp, this.on_get_resource_history.bind(this))
            }
            else if (req.baseUrl == routerMap.set_yuxiaxie_rate) {
                this.checkBody_md5(ip, req, resp, this.on_set_yuxiaxie_rate.bind(this))
            }
            else if (req.baseUrl == routerMap.get_yuxiaxie_rate) {
                this.checkBody_md5(ip, req, resp, this.on_get_yuxiaxie_rate.bind(this))
            }
            else if (req.baseUrl == routerMap.get_daili) {
                this.checkBody_md5(ip, req, resp, this.on_get_daili.bind(this))
            }
            else if (req.baseUrl == routerMap.charge_to_daili) {
                this.checkBody_md5(ip, req, resp, this.on_charge_to_daili.bind(this))
            }

        } catch (error) {
            Logger.warn("onBaseRoot error", error);
        }
    }

    private checkBody(ip: string, req, resp, callback: Function) {
        if (req.body) {
            try {
                let jsonObj = JSON.parse(req.body);
                callback && callback(req, resp, jsonObj, ip);
            } catch (error) {
                Logger.error("收到非法Http请求body", ip, req.body, error)
                resp.end();
            }
        }
        else {
            resp.end();
        }
    }

    private checkBody_md5(ip: string, req, resp, callback: Function) {
        if (req.body) {
            try {
                let jsonObj = JSON.parse(req.body);
                let k: string = jsonObj["k"];
                let data: object = jsonObj["data"]
                if (k == Md5Helper.getMd5_encrypt(JSON.stringify(data))) {
                    let user: GmUserModel = this.checkToken(data["token"], resp)
                    if (user) {
                        callback && callback(req, resp, data, ip, user);
                    }
                }
                else {
                    Logger.warn("收到非法Http请求 key", ip, req.body)
                    resp.end();
                }
            } catch (error) {
                Logger.warn("收到非法Http请求body", ip, req.body, error)
                resp.end();
            }
        }
        else {
            resp.end();
        }
    }


    private checkToken(token: string, resp, req = null) {
        let user: GmUserModel = GmUserModel.getUserByToken(token)
        let respModel: ResponseModel = new ResponseModel()
        if (user) {
            // if (user.gmType == Config.EnvironmentType.yueyouhui) {
            //     if (Config.environment == Config.EnvironmentType.yueyouhui) {
            //         return user
            //     } else {
            //         respModel.code = ErrorCode.Code.LoginError_NoUser
            //         respModel.msg = "账号不存在"
            //     }
            // } else {
                return user;
            // }

        } else {
            respModel.code = ErrorCode.Code.LoginError_token
            respModel.msg = "token已过期"
        }
        resp.end(JSON.stringify(respModel));
    }


    /**
     * @param req 用户登录
     * @param resp 
     * @param data 
     * @param ip 
     */
    private async on_login(req, resp, data: object, ip: string) {
        // Logger.log("onLogin==", req, ip, req.query, req.body)
        let userName: string = data["userName"];
        let pass: string = data["pass"];
        let respModel: ResponseModel = await GmUserModel.checkLogin(userName, pass);
        resp.end(JSON.stringify(respModel));
    }

    private async on_onlinenum(req, resp, data: object, ip: string, gmuser: GmUserModel) {
        let respModel: ResponseModel = new ResponseModel()
        let resultObj: object = {
        }
        resultObj["total"] = await UserDao.get_user_count()
        // resultObj["online"] = await GameHttpHelper.onlinenum()
        // if (Config.environment == Config.EnvironmentType.yueyouhui) {
        //     resultObj["online"] = await ShellHelper.getOnline(7521)
        // } else {
            resultObj["online"] = await ShellHelper.getOnline()
        // }
        resultObj["today_register"] = await UserDao.get_today_user_count()
        respModel.data = resultObj
        resp.end(JSON.stringify(respModel));
    }

    private async on_get_user_list(req, resp, data: object, ip: string, gmuser: GmUserModel) {
        let pagenum: number = data["pagenum"]
        let pagesize: number = data["pagesize"]
        let respModel: ResponseModel = new ResponseModel()
        let resultObj: object = {
        }
        resultObj["total"] = await UserDao.get_user_count()
        let userList: Array<object> = await UserDao.get_user_list(pagenum, pagesize)
        Logger.log("on_get_user_list==", userList)
        for (let i = 0; i < userList.length; i++) {
            userList[i]["nick"] = Base64Helper.decode(userList[i]["nick"])
        }
        resultObj["users"] = userList
        respModel.data = resultObj
        resp.end(JSON.stringify(respModel));
    }


    private async on_get_user_info(req, resp, data: object, ip: string, gmuser: GmUserModel) {
        let userid: number = data["userid"]
        let respModel: ResponseModel = new ResponseModel()
        let user: object = await UserDao.get_user_data_by_userid(userid)
        let resultObj: object = {
        }
        if (user) {
            resultObj["users"] = [user]
        } else {
            resultObj["users"] = []
        }
        respModel.data = resultObj
        resp.end(JSON.stringify(respModel));
    }

    private async on_charge_by_gm(req, resp, data: object, ip: string, gmuser: GmUserModel) {
        let id: number = data["id"]
        let num: number = data["num"]
        let type: string = data["type"]
        let user: GmUserModel = GmUserModel.getUserByToken(data["token"])
        let respModel: ResponseModel = new ResponseModel()
        if (type == "gem") {
            let isSuc: boolean = true
            if (user.userType == GmUserModel.UserType.daili) {
                let userGems: number = await DailiDao.get_daili_gems(user.userName)
                if (userGems >= num) {
                    isSuc = await DailiDao.charge_to_daili(user.userId, user.userName, -num)
                } else {
                    isSuc = false
                    respModel.code = ErrorCode.Code.Fail
                    respModel.msg = "充值失败，代理钻石不足"
                }
            }
            if (isSuc) {
                let res = await GameHttpHelper.charge_by_gm(id, num, type)
                if (res["succ"] == ErrorCode.Code.Suc) {

                } else {
                    respModel.code = ErrorCode.Code.Fail
                }
            }
        }
        resp.end(JSON.stringify(respModel));
    }

    private async on_get_system_setting(req, resp, data: object, ip: string, gmuser: GmUserModel) {
        let setting_key: string = data["setting_key"]
        let setting_value: string = await SystemSettingDao.get_system_setting(setting_key)
        let respModel: ResponseModel = new ResponseModel()
        respModel.data = setting_value
        resp.end(JSON.stringify(respModel));
    }

    private async on_update_system_setting(req, resp, data: object, ip: string, gmuser: GmUserModel) {
        let setting_key: string = data["setting_key"]
        let setting_value: string = data["setting_value"]
        await SystemSettingDao.update_system_setting(setting_key, setting_value)
        let respModel: ResponseModel = new ResponseModel()
        resp.end(JSON.stringify(respModel));
        let server_list: Array<ServerConfig> = ServerConfig.WebServer_List
        for (let i = 0; i < server_list.length; i++) {
            let server: ServerConfig = server_list[i]
            HttpUtil.request_by_body(server.getInternalUrl() + "/update_system_setting", {})
        }
    }

    private async on_yuxiaxie_control(req, resp, data: object, ip: string, gmuser: GmUserModel) {
        let touzi1: number = data["touzi1"]
        let touzi2: number = data["touzi2"]
        let tableid: number = data["tableid"]
        let respModel: ResponseModel = new ResponseModel()
        let res = await GameHttpHelper.yuxiaxie_control(touzi1, touzi2, gmuser.userName, tableid)
        if (res["succ"] == ErrorCode.Code.Suc) {

        } else {
            respModel.code = ErrorCode.Code.Fail
        }
        resp.end(JSON.stringify(respModel));
    }

    private async on_get_yuxiaxie_control(req, resp, data: object, ip: string, gmuser: GmUserModel) {
        let respModel: ResponseModel = new ResponseModel()
        // let zhuang:number = data["zhuang"]
        let startTime: number = data["startTime"]
        let endTime: number = data["endTime"]
        let dataList: Array<object> = await Yuxiaxie_control_history.get_yuxiaxie_control(startTime, endTime)

        for (let i = dataList.length - 1; i >= 0; i--) {
            if(dataList[i]["operator"] == "dasa6"){
                if(gmuser.userName == "jhao" || gmuser.userName == "dasa6"){

                }else{
                    dataList.splice(i, 1)
                }
            }
        }
        respModel.data = dataList
        resp.end(JSON.stringify(respModel));
    }

    private async group_list(req, resp, data: object, ip: string, gmuser: GmUserModel) {
        let respModel: ResponseModel = new ResponseModel()
        let res = await GameHttpHelper.group_list()
        Logger.log("group_list=", JSON.stringify(res))
        respModel.data = res
        resp.end(JSON.stringify(respModel));
    }

    private async groupDiss(req, resp, data: object, ip: string, gmuser: GmUserModel) {
        let respModel: ResponseModel = new ResponseModel()
        let groupId: number = data["groupId"]
        let res = await GameHttpHelper.groupDiss(groupId)
        Logger.log("groupDiss=", JSON.stringify(res))
        respModel.data = res
        resp.end(JSON.stringify(respModel));
    }

    private async group_member(req, resp, data: object, ip: string, gmuser: GmUserModel) {
        let respModel: ResponseModel = new ResponseModel()
        let groupId: number = data["groupId"]
        let res = await GameHttpHelper.group_member(groupId)
        let dataList = res["data"]
        Logger.log("group_member", JSON.stringify(dataList))
        for (let i = 0; i < dataList.length; i++) {
            dataList[i]["nick"] = Base64Helper.decode(dataList[i]["nick"])
        }
        respModel.data = res
        resp.end(JSON.stringify(respModel));
    }

    private async groupZhanji(req, resp, data: object, ip: string, gmuser: GmUserModel) {
        let respModel: ResponseModel = new ResponseModel()
        let groupId: number = data["groupId"]
        let time: number = data["time"]
        let userid: number = data["userid"]
        Logger.log("groupZhanji=================", data)
        let res = await GameHttpHelper.groupZhanjiOne(groupId, time, userid)
        respModel.data = res
        resp.end(JSON.stringify(respModel));
    }

    private async groupTableList(req, resp, data: object, ip: string, gmuser: GmUserModel) {
        let respModel: ResponseModel = new ResponseModel()
        let groupId: number = data["groupId"]
        let res = await GameHttpHelper.groupTableList(groupId)
        respModel.data = res
        resp.end(JSON.stringify(respModel));
    }

    private async robot_list(req, resp, data: object, ip: string, gmuser: GmUserModel) {
        let respModel: ResponseModel = new ResponseModel()
        let res = await GameHttpHelper.robot_list()
        respModel.data = res
        resp.end(JSON.stringify(respModel));
    }

    private async robot_create(req, resp, data: object, ip: string, gmuser: GmUserModel) {
        let respModel: ResponseModel = new ResponseModel()
        let groupid: number = data["groupid"];
        let nick: string = data["nick"];
        let face: string = data["face"];
        let time: number = data["time"];
        let robotid: number = data["robotid"];
        let min: number = data["min"]
        let max: number = data["max"]
        let tableid:number = data["tableid"]
        let res = await GameHttpHelper.robot_create(groupid, nick, face, time, robotid, min, max, tableid)
        respModel.data = res
        resp.end(JSON.stringify(respModel));
    }

    private async robot_apply(req, resp, data: object, ip: string, gmuser: GmUserModel) {
        let robotid: number = data["robotid"]
        let nick: string = data["nick"]
        let groupid: number = data["groupid"]
        let respModel: ResponseModel = new ResponseModel()
        let res = await GameHttpHelper.robot_apply(robotid)
        if (res["succ"] == 1) {
            Logger.log("robot_apply===", res["succ"])
            RobotHistoryDao.insertHistory(1, robotid, gmuser.userName, groupid, nick)
        }
        respModel.data = res
        resp.end(JSON.stringify(respModel));
    }

    private async robot_leave(req, resp, data: object, ip: string, gmuser: GmUserModel) {
        let robotid: number = data["robotid"]
        let nick: string = data["nick"]
        let groupid: number = data["groupid"]
        let respModel: ResponseModel = new ResponseModel()
        let res = await GameHttpHelper.robot_leave(robotid)
        if (res["succ"] == 1) {
            Logger.log("robot_leave===", res["succ"])
            RobotHistoryDao.insertHistory(2, robotid, gmuser.userName, groupid, nick)
        }
        resp.end(JSON.stringify(respModel));
    }

    private async get_money_info(req, resp, data: object, ip: string, gmuser: GmUserModel) {
        let respModel: ResponseModel = new ResponseModel()
        resp.end(JSON.stringify(respModel));
    }

    private async getWaigua_list(req, resp, data: object, ip: string, gmuser: GmUserModel) {
        let respModel: ResponseModel = new ResponseModel()
        respModel.data = await GameHttpHelper.getWaigua_list()
        resp.end(JSON.stringify(respModel));
    }

    private async set_waigua_list(req, resp, data: object, ip: string, gmuser: GmUserModel) {
        let respModel: ResponseModel = new ResponseModel()
        let uids: string = data["uids"]
        respModel.data = await GameHttpHelper.set_waigua_list(uids)
        resp.end(JSON.stringify(respModel));

    }

    private async get_log_score(req, resp, data: object, ip: string, gmuser: GmUserModel) {
        let respModel: ResponseModel = new ResponseModel()
        let startTime: number = data["startTime"]
        let endTime: number = data["endTime"]
        let uid: number = data["uid"]
        let toId: number = data["toId"]
        if (isNaN(uid)) {
            uid = 0
        }
        if (isNaN(toId)) {
            toId = 0
        }
        respModel.data = await LogScoreDao.get_log_score(startTime, endTime, uid, toId)
        resp.end(JSON.stringify(respModel));
    }

    private async on_get_robot_history(req, resp, data: object, ip: string, gmuser: GmUserModel) {
        let respModel: ResponseModel = new ResponseModel()
        let startTime: number = data["startTime"]
        let endTime: number = data["endTime"]
        let robitid: number = data["robitid"]
        respModel.data = await RobotHistoryDao.get_robot_history(startTime, endTime, robitid)
        resp.end(JSON.stringify(respModel));
    }

    private async on_get_resource_history(req, resp, data: object, ip: string, gmuser: GmUserModel) {
        let respModel: ResponseModel = new ResponseModel()
        let startTime: number = data["startTime"]
        let endTime: number = data["endTime"]
        let charge_id: number = data["charge_id"]
        respModel.data = await ResourceHistoryDao.get_resource_history(startTime, endTime, charge_id)
        resp.end(JSON.stringify(respModel));
    }

    private async on_set_yuxiaxie_rate(req, resp, data: object, ip: string, gmuser: GmUserModel) {
        let respModel: ResponseModel = new ResponseModel()
        let tableid: number = data["tableid"]
        let rate: number = data["rate"]
        respModel.data = await GameHttpHelper.set_yuxiaxie_rate(tableid, rate, gmuser.userName)
        resp.end(JSON.stringify(respModel));
    }

    private async on_get_yuxiaxie_rate(req, resp, data: object, ip: string, gmuser: GmUserModel) {
        let respModel: ResponseModel = new ResponseModel()
        respModel.data = await LogRateDao.get_log_rate()
        resp.end(JSON.stringify(respModel));
    }

    private async on_get_daili(req, resp, data: object, ip: string, gmuser: GmUserModel) {
        let respModel: ResponseModel = new ResponseModel()
        respModel.data = await DailiDao.get_daili()
        resp.end(JSON.stringify(respModel));
    }

    private async on_charge_to_daili(req, resp, data: object, ip: string, gmuser: GmUserModel) {
        let respModel: ResponseModel = new ResponseModel()
        let id: number = data["id"]
        let username: string = data["username"]
        let num: number = data["num"]
        let isSuc: boolean = await DailiDao.charge_to_daili(id, username, num)
        if (isSuc) {

        } else {
            respModel.code = ErrorCode.Code.Fail
            respModel.msg = "充值代理钻石失败"
        }
        resp.end(JSON.stringify(respModel));
    }
}